#ifndef __YAFFS_DEFY_H__
#define __YAFFS_DEFY_H__

#include <linux/crypto.h>
#include <linux/err.h>
#include <linux/scatterlist.h>
#include "yaffs_guts.h"

#define DEFY_ENCRYPT 1
#define DEFY_DECRYPT 0
#define DEFY_HASH_FUNCTION "hmac(md5)"
#define DEFY_CRYPTO_FUNCTION "cbc(aes)"
#define DEFY_KEY_LENGTH 16
#define DEFY_ID_LENGTH 16
#define DEFY_LOGIN_PORT 5555
#define BEGIN_F 1
#define END_F -1
#define IN_F 0
#define PRF_OUT_LEN 20

struct defy_chunk {
    struct yaffs_ext_tags *tags;
    u8 *data;
};

struct defy_marker {
    char level_id[DEFY_ID_LENGTH + 1];
    u8 next_level_key[DEFY_KEY_LENGTH];
    int chunk;
    u8 *bitmap;
};

struct defy_level_info {
    u8 level_key[DEFY_KEY_LENGTH];
    int cached_chunks;
    int block_to_write;
    int defy_level;
    u32 seq_number;
    struct defy_level_info *prev_level, *next_level;
    struct defy_chunk *cache;
    struct defy_marker *marker;
};

void defy_printk(const char *input, const int indent);
void defy_printk_indent(void);
void defy_printk_break(void);
void print_hex(const u8 *input, const int length);
void print_block_info(const struct yaffs_block_info *bi, int chunk_id);
void defy_cipher(struct yaffs_dev *dev, u8 *buf, const int bufsize,
		 const int level, u8 *iv_byte, const int enc);
int defy_init(struct yaffs_dev *dev);
int defy_exit(struct yaffs_dev *dev);
int defy_cache_chunk(struct yaffs_dev *dev, const u8 *data,
		     struct yaffs_ext_tags *tags);
int defy_read_cached_chunk(struct yaffs_dev *dev, int nand_chunk, u8 *data,
			   struct yaffs_ext_tags *tags);
int defy_find_marker(struct yaffs_dev *dev, int blk, int level);
int defy_write_random_chunks(struct yaffs_dev *dev, int start_chunk);
int defy_remove_block_from_level(struct yaffs_dev *dev, int level_num,
				 int blk);
#endif
